package com.vcredit.creditcat.manager;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.config.annotation.Service;
import com.vcredit.bird.api.IBankCardService;
import com.vcredit.bird.enumtype.BankEnum;
import com.vcredit.bird.enumtype.CreditCardBankEnum;
import com.vcredit.bird.vo.custcard.BankCardBin;
import com.vcredit.creditcat.api.ICustCardManager;
import com.vcredit.creditcat.dto.CustCardDto;
import com.vcredit.creditcat.enumtype.AuthItemEnum;
import com.vcredit.creditcat.enumtype.BankCardTypeEnum;
import com.vcredit.creditcat.enumtype.CardStatusEnum;
import com.vcredit.creditcat.exception.CustCardExcetpion;
import com.vcredit.creditcat.model.AuthItem;
import com.vcredit.creditcat.model.AuthLog;
import com.vcredit.creditcat.model.Cust;
import com.vcredit.creditcat.model.CustCard;
import com.vcredit.creditcat.service.AuthLogService;
import com.vcredit.creditcat.service.CustCardService;
import com.vcredit.creditcat.service.product.util.EnumExtUtil;
import com.vcredit.framework.annotation.Log;
import com.vcredit.framework.util.BeanUtil;
import com.vcredit.framework.util.BeanUtilFilter;
import com.vcredit.framework.util.EnumUtil;

/**
 * @author chengchao
 *
 */
@Service(protocol = {"protocol1"}, version = "1.0")
public class CustCardManager implements ICustCardManager {

  @Autowired
  private CustCardService custCardService;

  @Autowired
  private IBankCardService bankCardService;

  @Autowired
  private CreditCatProcessManager creditCatProcessManager;

  @Autowired
  private AuthLogService authLogService;

  @Value("${card.four.guid}")
  private String source;

  @Log
  @Override
  public CustCardDto queryCardBin(String cardNo) throws CustCardExcetpion {
    BankCardBin bankCardBin = bankCardService.queryCardBin(cardNo);
    BankCardTypeEnum cardType = BankCardTypeEnum.CREDIT;

    // 判断是否借记卡
    if (bankCardBin.getIsCreditCard().indexOf(BankCardTypeEnum.DEBIT.getDesc()) > -1) {
      cardType = BankCardTypeEnum.DEBIT;
    }
    if (cardType.getCode() == BankCardTypeEnum.DEBIT.getCode()) {
      // 借记卡
      BankEnum bankEnum = bankCardBin.getBankEnum();
      return new CustCardDto(bankEnum.getCode(), bankEnum.getDesc(), cardType);
    } else {
      // 贷记卡
      CreditCardBankEnum creditCardBankEnum = bankCardBin.getCreditCardBankEnum();
      return new CustCardDto(creditCardBankEnum.getCode(), creditCardBankEnum.getDesc(), cardType);
    }
  }

  @Override
  public List<CustCardDto> queyCardsByCustId(Long custId, BankCardTypeEnum cardType) {
    List<CustCard> cards =
        null == cardType ? custCardService.findByCustId(custId) : custCardService
            .findByCustIdAndCardType(custId, cardType);
    return BeanUtil.copy(cards, CustCardDto.class, new BeanUtilFilter<CustCardDto, CustCard>() {
      @Override
      public CustCardDto filter(CustCard source, CustCardDto target) {
        BankCardTypeEnum enumOnValue = null;
        try {
          enumOnValue =
              EnumExtUtil.getEnumOnValue(BankCardTypeEnum.class,
                  String.valueOf(source.getCardType()), "code");
        } catch (Exception e) {
          e.printStackTrace();
        }
        target.setIsDefault(source.getIsDefault().equals("1"));
        target.setBankName(BankEnum.valueOf(source.getBankCode()).getDesc());
        target.setCardType(enumOnValue);
        return target;
      }
    });
  }

  @Override
  @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  public CustCardDto bindCustCard(Cust cust, CustCardDto cardDto) throws CustCardExcetpion {

    // 查询该卡号在系统中所有记录
    CustCard custCard = new CustCard();
    List<CustCard> cards =
        custCardService.findByCustIdNoAndCardNo(cust.getCustIdno(), cardDto.getAccountNo(),
            cardDto.getCardType());
    if (cards.size() == 0) {
      custCard.setCustId(cust.getCustId());
      custCard.setAccountIdno(cust.getCustIdno());
      custCard.setAccountName(cust.getCustName());
      custCard.setAccountNo(cardDto.getAccountNo());
      custCard.setBankCode(cardDto.getBankCode());
      custCard.setCardType(cardDto.getCardType().getCode());
      custCard.setCardStatus(CardStatusEnum.Valid.getCode());
      custCard.setReservedMobile(cardDto.getReservedMobile());
      custCard.setIsDefault("0");
      custCardService.insert(custCard);
    } else {
      for (CustCard card : cards) {
        if (card.getCustId().equals(cust.getCustId())) {
          custCard = card;
          break;
        } else {
          throw new CustCardExcetpion("该卡号已被其他账户绑定");
        }
      }
    }
    cardDto.setCardId(custCard.getCardId());
    cardDto.setIsDefault(custCard.getIsDefault().equals("1"));

    return cardDto;
  }

  @Override
  public CustCardDto bindCustCardAndItemDone(Cust cust, CustCardDto cardDto) throws Exception {
    CustCardDto cardDto1 = bindCustCard(cust, cardDto);
    // 认证完成
    creditCatProcessManager.itemDone(new AuthItem(AuthItemEnum.DEBIT_CARD.getCode()),
        cust.getLastProccessId());
    authLogService.insert(new AuthLog(cust.getLastProccessId(), cust.getCustId(),
        AuthItemEnum.DEBIT_CARD.getCode(), "", new Date()));
    return cardDto1;
  }

  @Log
  @Override
  public Boolean checkCustCard(String custName, String custIdNo, String accountNo, String mobile,
      String bankCode) throws CustCardExcetpion {
    // 校验验卡四要素是否为空
    if (StringUtils.isBlank(custName) || StringUtils.isBlank(custIdNo)
        || StringUtils.isBlank(accountNo) || StringUtils.isBlank(mobile)) {
      throw new CustCardExcetpion("用户信息不全");
    }

    return bankCardService.verifyCard(accountNo, custName, custIdNo, mobile,
        EnumUtil.valueOf(BankEnum.class, bankCode, "vbsEnum"), source);
  }

  @Override
  public CustCardDto queryByCardId(Long cardId) throws Exception {
    CustCardDto custCardDto = new CustCardDto();
    CustCard custCard = custCardService.findById(cardId);
    if (custCard == null) {
      return null;
    }
    BeanUtil.copy(custCard, custCardDto);
    return custCardDto;
  }

}
